﻿using SolidWorks.Interop.sldworks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace SolidworksDLL
{
    public class FeatureHelp
    {
        /// <summary>
        /// 得到模型的顶级特征
        /// </summary>
        /// <param name="swModel"></param>
        /// <param name="topOnly">true不返回子特征，false返回子特征</param>
        /// <returns></returns>
        public static List<FeatureData> GetTopFeature(ModelDoc2 swModel, bool topOnly)
        {
            List<FeatureData> features = new List<FeatureData>();
            Feature feature = (Feature)swModel.FirstFeature();
            TraFeature(ref features, feature, topOnly);
            return features;
        }

        public static void TraFeature(ref List<FeatureData> features, Feature feature, bool topOnly)
        {
            while (feature != null)
            {
                FeatureData featureData = new FeatureData();
                featureData.feature = feature;

                if (topOnly == false)
                {
                    //featureData.childrenFeature = new List<FeatureData>() };
                    //DealSubFeature(featureData);

                    //featureData = GetChildFeature(feature);

                    GetFolderSubFeat(featureData);
                }

                features.Add(featureData);
                feature = feature.GetNextFeature();
            }
        }

        /// <summary>
        /// 得到模型的顶级特征
        /// </summary>
        /// <param name="swModel"></param>
        /// <param name="topOnly">true不返回子特征，false返回子特征</param>
        /// <returns></returns>
        public static List<FeatureData> GetTopFeature(Component2 swModel, bool topOnly)
        {
            List<FeatureData> features = new List<FeatureData>();
            Feature feature = swModel.FirstFeature();
            TraFeature(ref features, feature, topOnly);
            return features;
        }

        public static FeatureData GetChildFeature(Feature feature)
        {
            FeatureData featureData = new FeatureData();
            featureData.feature = feature;

            List<FeatureData> features = new List<FeatureData>();
            featureData.childrenFeature = features;

            object[] objs = (object[])feature.GetChildren();
            if (objs != null && objs.Length > 0)
            {
                foreach (Feature item in objs)
                {
                    FeatureData childFeatureData = new FeatureData
                    { feature = item, childrenFeature = new List<FeatureData>() };

                    features.Add(childFeatureData);
                    TraChildFeature(childFeatureData);
                }
            }

            return featureData;
        }

        public static void TraChildFeature(FeatureData featureData)
        {
            List<FeatureData> features = new List<FeatureData>();
            featureData.childrenFeature = features;

            object[] objs = (object[])featureData.feature.GetChildren();
            if (objs != null && objs.Length > 0)
            {
                foreach (Feature item in objs)
                {
                    FeatureData childFeatureData = new FeatureData
                    { feature = item, childrenFeature = new List<FeatureData>() };

                    features.Add(childFeatureData);
                    TraChildFeature(childFeatureData);
                }
            }
        }

        public static void DealSubFeature(FeatureData featureData)
        {
            List<FeatureData> features = new List<FeatureData>();
            featureData.childrenFeature = features;

            Feature subFeature = featureData.feature.GetFirstSubFeature();

            while (subFeature != null)
            {
                FeatureData childFeatureData = new FeatureData
                { feature = subFeature, childrenFeature = new List<FeatureData>() };

                features.Add(featureData);
                DealSubFeature(childFeatureData);

                subFeature = subFeature.GetNextSubFeature();
            }
        }

        public static void GetFolderSubFeat(FeatureData featureData)
        {
            string FeatType = featureData.feature.Name;
            string FeatTypeName = featureData.feature.GetTypeName2();
            List<FeatureData> features = new List<FeatureData>();
            featureData.childrenFeature = features;
            if ((FeatTypeName == "FtrFolder" & !FeatType.Contains("EndTag")))
            {
                FeatureFolder swFeatFolder = (FeatureFolder)featureData.feature.GetSpecificFeature2();
                object[] Features = (object[])swFeatFolder.GetFeatures();
                if (Features != null && Features.Length > 0)
                {
                    foreach (Feature item in Features)
                    {
                        FeatureData childFeatureData = new FeatureData
                        { feature = item, childrenFeature = new List<FeatureData>() };

                        features.Add(childFeatureData);
                        TraChildFeature(childFeatureData);
                    }
                }
            }
        }
    }

    public class FeatureData
    {
        public Feature feature;
        //public int Id;
        //public int ParId;

        public List<FeatureData> childrenFeature;
    }

    public class TreeItemData
    {
        public TreeControlItem node;
        //public int Id;
        //public int ParId;

        public List<TreeItemData> childrenNode;
    }

    public class TreeItemHelp
    {
        public static TreeItemData GetAllNode(ModelDoc2 swModel)
        {
            FeatureManager featureMgr = swModel.FeatureManager;
            TreeControlItem rootNode = featureMgr.GetFeatureTreeRootItem2(0);
            TreeItemData treeItemData = new TreeItemData { node = rootNode };
            treeItemData.childrenNode = new List<TreeItemData>();
            TraNode(treeItemData);
            return treeItemData;
        }

        public static void TraNode(TreeItemData nodeData)
        {
            TreeControlItem childNode = nodeData.node.GetFirstChild();
            while (childNode != null)
            {
                TreeItemData treeItemData = new TreeItemData { node = childNode };
                treeItemData.childrenNode = new List<TreeItemData>();
                nodeData.childrenNode.Add(treeItemData);
                TraNode(treeItemData);
                childNode = childNode.GetNext();
            }
        }
    }
}